using FireStarterModeller.BO;
using FireStarterModeller.Logic.Commands;
using FireStarterModeller.Test.BO;
using Habanero.Base.Exceptions;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic.Commands
{
    [TestFixture]
    public class TestRenameAssemblyCommand
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            TestUtilsLogic.SetupFixture();
        }
        [SetUp]
        public void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }

        [Test]
        public void TestApply()
        {
            //---------------Set up test pack-------------------
            DMAssembly assembly = TestUtilsShared.CreateDMAssembly();
            assembly.Name = "OriginalName";
            assembly.Save();
            ICommandFactory commandFactory = new CommandFactory();
            const string newName = "NewName";

            //---------------Execute Test ----------------------
            ICommand command = commandFactory.CreateRenameAssembly(assembly, newName);
            command.Apply();

            //---------------Test Result -----------------------
            Assert.AreEqual(newName, assembly.Name);

            //---------------Tear Down -------------------------          
        }

        [Test]
        public void TestApply_Failure_Duplicate()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            DMAssembly assembly2 = dmSolution.CreateAssembly("Assembly2");
            assembly2.Save();
            const string assembly3name = "Assembly3";
            DMAssembly assembly3 = dmSolution.CreateAssembly(assembly3name);
            assembly3.Save();
            
            ICommandFactory commandFactory = new CommandFactory();
            
            //---------------Execute Test ----------------------
            try
            {
                ICommand command = commandFactory.CreateRenameAssembly(assembly3, assembly2.Name);
                command.Apply();
                Assert.Fail("Shouldn't save successfully as there is a duplicate assembly");
            } catch (HabaneroApplicationException ex)
            {
                StringAssert.Contains("already exists with the same identifier:", ex.Message);
            }
            Assert.AreEqual(assembly3name, assembly3.Name);

            //---------------Tear Down -------------------------          
        }

        [Test]
        public void Test_Revert()
        {
            DMAssembly assembly = TestUtilsShared.CreateDMAssembly();
            const string originalname = "OriginalName";
            assembly.Name = originalname;
            assembly.Save();
            ICommandFactory commandFactory = new CommandFactory();
            const string newName = "NewName";
            ICommand command = commandFactory.CreateRenameAssembly(assembly, newName);
            command.Apply();

            //---------------Assert preconditions---------------
            Assert.AreEqual(newName, assembly.Name);
            //---------------Execute Test ----------------------
            command.Revert();
            //---------------Test Result -----------------------
            Assert.AreSame(originalname, assembly.Name);
            //---------------Tear Down -------------------------          
        }

        [Test]
        public void Test_Revert_Fail_Duplicate()
        {
            DMSolution solution = TestUtilsShared.CreateSavedDMSolution();
            const string originalname = "OriginalName";
            DMAssembly assembly = solution.CreateAssembly(originalname);
            assembly.Save();
            ICommandFactory commandFactory = new CommandFactory();
            const string newName = "NewName";

            ICommand command = commandFactory.CreateRenameAssembly(assembly, newName);
            command.Apply();

            DMAssembly assembly2 = solution.CreateAssembly(originalname);
            assembly2.Save();

            //---------------Assert preconditions---------------
            Assert.AreEqual(newName, assembly.Name);
            //---------------Execute Test ----------------------
            try
            {
                command.Revert();
                Assert.Fail("Revert should fail as there is now a duplicate assembly");
            } 
            //---------------Test Result -----------------------
            catch (HabaneroApplicationException)
            {
                Assert.AreSame(newName, assembly.Name);                
            }

            //---------------Tear Down -------------------------          
        }
    }
}
